import { message as Message, Modal } from 'antd';
import axios, { AxiosRequestConfig, AxiosError, AxiosResponse } from 'axios';

import { t } from '@/locales/i18n';
import userStore from '@/store/userStore';

import { Result } from '#/api';

// 创建 axios 实例
const axiosInstance = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 50000,
  headers: { 'Content-Type': 'application/json;charset=utf-8' },
});

// 请求拦截
axiosInstance.interceptors.request.use(
  (config) => {
    // 在请求被发送之前做些什么
    config.headers['X-Requested-With'] = 'Hiwie-Fetch';
    return config;
  },
  (error) => {
    // 请求错误时做些什么
    return Promise.reject(error);
  },
);

// 响应拦截
axiosInstance.interceptors.response.use(
  (res: AxiosResponse<Result>) => {
    if (!res.data) throw new Error(t('sys.api.apiRequestFailed'));
    if (res.config.responseType === 'blob') return Promise.resolve(res);
    const { error, success } = res.data;
    // 业务请求成功
    if (!error) {
      return success;
    }

    // 业务请求错误
    Message.error(error.message);
    throw new Error(error.message || t('sys.api.apiRequestFailed'));
  },
  (error: AxiosError<Result>) => {
    const { response, message } = error || {};
    const status = response?.status;
    if (status === 401) {
      Modal.confirm({
        title: '系统提示',
        content: '登录状态已过期，您可以继续留在该页面，或者重新登录',
        cancelText: '取消',
        okText: '重新登录',
        onOk: () => {
          userStore.getState().actions.clearUserInfoAndToken();
          Modal.destroyAll();
        },
        onCancel: () => {
          Modal.destroyAll();
        },
      });
    } else if (status === 400) {
      Message.error(t('sys.api.errorMessage'));
    } else if (status === 403) {
      Message.error('操作权限不足，请联系管理员');
    }
    const errMsg = response?.data.error.message || message || t('sys.api.errorMessage');

    Message.error(errMsg);
    return Promise.reject(error);
  },
);

class APIClient {
  get<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.request({ ...config, method: 'GET' });
  }

  patch<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.request({ ...config, method: 'PATCH' });
  }

  post<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.request({ ...config, method: 'POST' });
  }

  put<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.request({ ...config, method: 'PUT' });
  }

  delete<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.request({ ...config, method: 'DELETE' });
  }

  request<T = any>(config: AxiosRequestConfig): Promise<T> {
    return new Promise((resolve, reject) => {
      axiosInstance
        .request<any, AxiosResponse<Result>>(config)
        .then((res: AxiosResponse<Result>) => {
          resolve(res as unknown as Promise<T>);
        })
        .catch((e: Error | AxiosError) => {
          reject(e);
        });
    });
  }

  // 文件名处理
  getFileNameFromHeaders = (response: AxiosResponse) => {
    // 从响应头中获取Content-Disposition信息
    const contentDisposition = response.headers['content-disposition'];

    // 使用正则表达式匹配文件名
    const match = /filename="(.*)"/.exec(contentDisposition);

    // 获取匹配的文件名
    return match ? decodeURI(match[1]) : 'unknown';
  };
}

export default new APIClient();
